package org.ims.inv.service.flow.impl;

import java.util.List;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.ims.inv.dao.flow.DAOFlowMaterial;
import org.ims.inv.model.flow.material.ModelFlowMaterial;
import org.ims.inv.service.flow.ServiceFlowMaterial;

import cn.trymore.core.exception.DAOException;
import cn.trymore.core.exception.ServiceException;
import cn.trymore.core.service.impl.ServiceGenericImpl;
import cn.trymore.core.util.UtilCollection;
import cn.trymore.core.util.UtilString;

/**
 * Service: 工作流材料
 * 
 * @author Jeccy.Zhao
 *
 */
public class ServiceFlowMaterialImpl
extends ServiceGenericImpl<ModelFlowMaterial> implements ServiceFlowMaterial
{
	
	/**
	 * Repository of flow material
	 */
	private DAOFlowMaterial daoFlowMaterial;
	
	public ServiceFlowMaterialImpl(DAOFlowMaterial dao)
	{
		super(dao);
		this.daoFlowMaterial = dao;
	}
	
	/*
	 * (non-Javadoc)
	 * @see org.ims.inv.service.flow.ServiceFlowMaterial#getAllRootMaterials()
	 */
	public List<ModelFlowMaterial> getAllRootMaterials () throws ServiceException
	{
		try
		{
			return this.daoFlowMaterial.getListByCriteria(this.getCriterias(new ModelFlowMaterial()));
		} 
		catch (DAOException e)
		{
			throw new ServiceException(e);
		}
	}
	
	/*
	 * (non-Javadoc)
	 * @see org.ims.inv.service.flow.ServiceFlowMaterial#getBySequence(java.lang.Integer, org.ims.inv.model.flow.material.ModelFlowMaterial)
	 */
	public ModelFlowMaterial getBySequence (Integer sequence, ModelFlowMaterial domain) throws ServiceException
	{
		try
		{
			ModelFlowMaterial entity = new ModelFlowMaterial();
			
			if (domain != null)
			{
				entity.setMaterialParent(domain.getMaterialParent());
			}			entity.setSequence(sequence);
			
			List<ModelFlowMaterial> result = this.daoFlowMaterial.getListByCriteria(this.getCriterias(entity));
			if (UtilCollection.isNotEmpty(result) && result.size() == 1)
			{
				return result.get(0);
			}
			else
			{
				throw new ServiceException("More than one entity was found");
			}
		}
		catch (DAOException e)
		{
			throw new ServiceException(e);
		}
	}
	
	/*
	 * (non-Javadoc)
	 * @see cn.trymore.core.service.impl.ServiceGenericImpl#getCriterias(cn.trymore.core.model.ModelBase)
	 */
	@Override
	protected DetachedCriteria getCriterias(ModelFlowMaterial domain)
	{
		DetachedCriteria criteria = DetachedCriteria.forClass(ModelFlowMaterial.class);
		
		if (domain != null)
		{
			if (domain.getMaterialParent() == null)
			{
				criteria.add(Restrictions.isNull("materialParent"));
			}
			else
			{
				criteria.createCriteria("materialParent").add(
						Restrictions.eq("id", domain.getMaterialParent().getId()));
			}
			
			if (domain.getSequence() != null)
			{
				criteria.add(Restrictions.eq("sequence", domain.getSequence()));
			}
			
			if (UtilString.isNotEmpty(domain.getMaterialName()))
			{
				criteria.add(Restrictions.like("materialName", domain.getMaterialName(), MatchMode.ANYWHERE));
			}
			
			if (UtilString.isNotEmpty(domain.getMaterialDesc()))
			{
				criteria.add(Restrictions.like("materialDesc", domain.getMaterialDesc(), MatchMode.ANYWHERE));
			}
			
		}
		
		criteria.add(Restrictions.isNotNull("sequence"));
		criteria.addOrder(Order.asc("sequence"));
		
		return criteria;
	}
	
	/*
	 * (non-Javadoc)
	 * @see org.ims.inv.service.flow.ServiceFlowMaterial#getByRootMaterial(org.ims.inv.model.flow.material.ModelFlowMaterial)
	 */
	@Override
	public List<ModelFlowMaterial> getByRootMaterial(ModelFlowMaterial root)
			throws ServiceException
	{
		try
		{
			ModelFlowMaterial entity = new ModelFlowMaterial();
			entity.setMaterialParent(root);
			return this.daoFlowMaterial.getListByCriteria(this.getCriterias(entity));
		} 
		catch (DAOException e)
		{
			throw new ServiceException(e);
		}
	}
	
	public void setDaoFlowMaterial(DAOFlowMaterial daoFlowMaterial)
	{
		this.daoFlowMaterial = daoFlowMaterial;
	}

	public DAOFlowMaterial getDaoFlowMaterial()
	{
		return daoFlowMaterial;
	}

}
